jQuery.namespace = function (str, noclobber) {
    var i, a = str.split("."),
        o = window,
        callthrough = false;
    if (/[^a-zA-Z.]/.test(str)) {
        return false
    }
    for (i = 0; i < a.length; i++) {
        if (!o[a[i]]) {
            o[a[i]] = {};
            callthrough = true
        }
        o = o[a[i]]
    }
    if ( !! noclobber) {
        return callthrough
    }
    return true
};
AJS.$.fn.serializeArray = function () {
    return this.map(function () {
        return jQuery.nodeName(this, "form") ? jQuery.makeArray(this.elements) : this
    }).filter(function () {
        return this.name && !this.disabled && (this.checked || /select|textarea/i.test(this.nodeName) || /text|hidden|password/i.test(this.type))
    }).map(function (i, elem) {
        var val = jQuery(this).val();
        if (val == null) {
            val = ""
        }
        return val.constructor == Array ? jQuery.map(val, function (val, i) {
            return {
                name: elem.name,
                value: val
            }
        }) : {
            name: elem.name,
            value: val
        }
    }).get()
};
AJS.$.extend({
    put: function (url, data, callback, type) {
        if (jQuery.isFunction(data)) {
            callback = data;
            data = {}
        }
        return AJS.$.ajax({
            type: "PUT",
            url: url,
            data: data,
            success: callback,
            dataType: type
        })
    },
    del: function (url, data, callback, type) {
        if (jQuery.isFunction(data)) {
            callback = data;
            data = {}
        }
        return AJS.$.ajax({
            type: "delete",
            url: url,
            data: data,
            success: callback,
            dataType: type
        })
    },
    ajax: function (ajax) {
        var activeReq = 0,
            dressResponse = function (xhr) {
                var res = {};
                res.rc = xhr.status;
                if (xhr.responseText !== "") {
                    res.data = gadgets.json.parse(xhr.responseText)
                }
                return res
            };
        AJS.$.each("ajaxOpen,ajaxClosed,ajaxOauthApproval".split(","), function (i, o) {
            AJS.$.fn[o] = function (f) {
                return this.bind(o, f)
            }
        });
        AJS.$(document).ajaxSend(function (evt, req, options) {
            if (++activeReq === 1) {
                AJS.$.event.trigger("ajaxOpen", [req, options])
            }
        });
        AJS.$(document).ajaxComplete(function (evt, req, options) {
            if (--activeReq === 0) {
                AJS.$.event.trigger("ajaxClosed", [req, options])
            }
        });
        AJS.$.fn.ajaxComplete = function (f) {
            f = function (actualF) {
                return function (evt, response, options) {
                    if (response.status) {
                        actualF.call(this, evt, response, options)
                    } else {
                        actualF.apply(this, arguments)
                    }
                }
            }(f);
            return this.bind("ajaxComplete", f)
        };
        AJS.$.fn.ajaxError = function (f) {
            f = function (actualF) {
                return function (evt, response, options) {
                    if (response.status) {
                        actualF.call(this, evt, dressResponse(response), options)
                    } else {
                        actualF.apply(this, arguments)
                    }
                }
            }(f);
            return this.bind("ajaxError", f)
        };
        return function (usrOptions) {
            var reqOptions = {};
            var xhr = {
                status: 0,
                abort: function () {
                    reqOptions.success = function () {}
                }
            };
            if (typeof options === "string") {
                options = {
                    url: options
                }
            }
            var options = usrOptions;
            for (var name in AJS.$.ajaxSettings) {
                if (!options[name] && options[name] !== false) {
                    options[name] = AJS.$.ajaxSettings[name]
                }
            }
            if (options.baseUrl) {
                if (!/^(http)|(https):\/\//.test(options.url)) {
                    options.url = options.baseUrl + options.url
                }
            }
            if (typeof atlassian !== "undefined" && atlassian.util) {
                if (atlassian.util.getRendererBaseUrl() === options.baseUrl && new RegExp(options.baseUrl).test(options.url)) {
                    if (options.error) {
                        options.error = function (error) {
                            return function (xhr, type) {
                                if (!xhr.responseText) {
                                    options.success.apply(this, arguments)
                                } else {
                                    error.call(this, dressResponse(xhr))
                                }
                                options.error = error
                            }
                        }(options.error)
                    }
                    return ajax.call(this, options)
                }
            }
            var gadgetContentType = options.dataType.toUpperCase();
            switch (gadgetContentType) {
            case "XML":
                gadgetContentType = "DOM";
            case "JSON":
            case "TEXT":
                reqOptions[gadgets.io.RequestParameters.CONTENT_TYPE] = gadgets.io.ContentType[gadgetContentType];
                break;
            default:
                if (options.error) {
                    options.error({
                        status: 406
                    }, options)
                } else {
                    AJS.$.event.trigger("ajaxError", [{
                        status: 406
                    },
                    options])
                }
                return
            }
            reqOptions[gadgets.io.RequestParameters.METHOD] = gadgets.io.MethodType[options.type.toUpperCase()];
            reqOptions.url = options.url;
            reqOptions.OWNER_SIGNED = options.signOwner;
            reqOptions.VIEWER_SIGNED = options.signViewer;
            if (options.headers) {
                reqOptions[gadgets.io.RequestParameters.HEADERS] = options.headers
            }
            if (options.authorization) {
                reqOptions[gadgets.io.RequestParameters.AUTHORIZATION] = gadgets.io.AuthorizationType[options.authorization.toUpperCase()]
            }
            if (options.useToken) {
                reqOptions["OAUTH_USE_TOKEN"] = options.useToken
            }
            if (options.oauthServiceName) {
                reqOptions[gadgets.io.RequestParameters.OAUTH_SERVICE_NAME] = options.oauthServiceName
            }
            if (options.summaries) {
                reqOptions[gadgets.io.RequestParameters.GET_SUMMARIES] = options.summaries
            }
            if (options.entries) {
                reqOptions[gadgets.io.RequestParameters.NUM_ENTRIES] = options.entries
            }
            if (options.data) {
                if (options.type.toLowerCase() == "get") {
                    var prefix;
                    if (reqOptions.url.indexOf("?") >= 0) {
                        if (reqOptions.url.lastIndexOf("&") == reqOptions.url.length - 1) {
                            prefix = ""
                        } else {
                            prefix = "&"
                        }
                    } else {
                        prefix = "?"
                    }
                    if (typeof options.data == "string") {
                        reqOptions.url += (prefix + options.data.replace(/^\?/, ""))
                    } else {
                        reqOptions.url += (prefix + gadgets.io.encodeValues(options.data).replace(/^\?/, ""))
                    }
                } else {
                    reqOptions[gadgets.io.RequestParameters.POST_DATA] = options.data
                }
            }
            reqOptions.success = function (response) {
                xhr.status = response.rc;
                if (options.complete) {
                    options.complete(response, options)
                }
                if (options.global) {
                    AJS.$.event.trigger("ajaxComplete", [response, options])
                }
                if (response.errors && response.errors.length || response.oauthError) {
                    if (options.error) {
                        options.error(response, options)
                    }
                    if (options.global) {
                        AJS.$.event.trigger("ajaxError", [response, options])
                    }
                    return
                }
                if (options.dataType.toLowerCase() === "json" && typeof response.data === "string") {
                    if (options.error) {
                        options.error(response, options)
                    }
                    if (options.global) {
                        AJS.$.event.trigger("ajaxError", [response, options])
                    }
                    return
                }
                if (response.rc !== 200) {
                    if (options.error) {
                        options.error(response, options)
                    }
                    if (options.global) {
                        AJS.$.event.trigger("ajaxError", [response, options])
                    }
                    return
                }
                if (options.success && (response || response.oauthApprovalUrl)) {
                    options.success(response.data || response, "success", xhr)
                }
                if (options.global) {
                    AJS.$.event.trigger("ajaxSuccess", [response.data, options])
                }
            };
            if (options.ajaxSend) {
                options.ajaxSend(options)
            }
            if (options.global) {
                AJS.$.event.trigger("ajaxSend", [options])
            }
            gadgets.io.makeRequest(reqOptions.url, reqOptions.success, reqOptions);
            return xhr
        }
    }(AJS.$.ajax)
});
AJS.$.namespace("AJS.gadgets.templater");
AJS.gadgets.templater.Base = function () {
    var cache, template, descriptor = function (args) {
            return args
        },
        callbacks = [],
        remoteArgs = [],
        args = [],
        renderTemplate = function () {
            var cache = {};
            return function (str, data) {
                var fn;
                if (!/\W/.test(str)) {
                    fn = cache[str]
                } else {
                    var fnString = "var p=[], print=function(){p.push.apply(p,arguments);};" + "with(obj){p.push('" + str.replace(/[\r\t\n]/g, " ").split("<%").join("\t").replace(/((^|%>)[^\t]*)'/g, "$1\r").replace(/\t=(.*?)%>/g, "',$1,'").split("\t").join("');").split("%>").join("p.push('").split("\r").join("\\'") + "');}return p.join('');";
                    fn = new Function("obj", fnString)
                }
                return data ? fn(data) : fn
            }
        }();
    return {
        getDescriptorData: function (callback) {
            var argLengthComparator = 0,
                that = this,
                formattedArgs = {};
            if (remoteArgs.length < 1) {
                AJS.$(args).each(function () {
                    formattedArgs[this.key] = this.data
                });
                if (callback) {
                    callback.call(that, descriptor(formattedArgs))
                } else {
                    return descriptor(formattedArgs)
                }
            }
            AJS.$(remoteArgs).each(function (i, item) {
                var reqOptions;
                if (typeof item.ajaxOptions === "string") {
                    reqOptions = {
                        url: this.ajaxOptions
                    }
                } else {
                    if (AJS.$.isFunction(item.ajaxOptions)) {
                        reqOptions = item.ajaxOptions()
                    } else {
                        reqOptions = item.ajaxOptions
                    }
                }
                reqOptions.success = function (response) {
                    ++argLengthComparator;
                    formattedArgs[remoteArgs[i].key] = response;
                    if (argLengthComparator === remoteArgs.length) {
                        var excuter = function () {
                                if (callback) {
                                    callback.call(that, descriptor(formattedArgs))
                                } else {
                                    return descriptor(formattedArgs)
                                }
                                return arguments.callee
                            }();
                        if (cache !== false) {
                            that.getDescriptorData = excuter
                        }
                    }
                };
                AJS.$.ajax(reqOptions)
            })
        },
        disableCache: function () {
            cache = false
        },
        setTemplate: function (templ) {
            template = templ
        },
        setDescriptor: function (desc) {
            descriptor = desc
        },
        addCallback: function (func) {
            callbacks.push(func)
        },
        setRemoteDescriptorArg: function (key, ajaxOptions) {
            remoteArgs.push({
                key: key,
                ajaxOptions: ajaxOptions
            })
        },
        setDescriptorArg: function (arg) {
            args.push(arg)
        },
        build: function (data) {
            var that = this;
            if (!data && data !== false) {
                this.getDescriptorData(this.build)
            } else {
                if (data !== false) {
                    if (typeof template === "string" && document.getElementById(template)) {
                        that.build.template = AJS.$("#" + template).html();
                        var fragment = renderTemplate(that.build.template, data);
                        AJS.$(callbacks).each(function () {
                            this.call(that, AJS.$(fragment), data)
                        })
                    } else {
                        if (AJS.$.isFunction(template)) {
                            template(data);
                            AJS.$(callbacks).each(function () {
                                this.call(that, data)
                            })
                        } else {
                            if (template.length > 50) {
                                that.build.template = template;
                                var fragment = renderTemplate(that.build.template, data);
                                AJS.$(callbacks).each(function () {
                                    this.call(that, AJS.$(fragment), data)
                                })
                            } else {
                                if (!that.build.template) {
                                    AJS.$.ajax({
                                        url: template,
                                        dataType: "text",
                                        success: function (response) {
                                            that.build.template = response;
                                            var fragment = renderTemplate(that.build.template, data);
                                            AJS.$(callbacks).each(function () {
                                                this.call(that, AJS.$(fragment), data)
                                            })
                                        }
                                    })
                                } else {
                                    var fragment = renderTemplate(that.build.template, data);
                                    AJS.$(callbacks).each(function () {
                                        this.call(that, AJS.$(fragment), data)
                                    })
                                }
                            }
                        }
                    }
                }
            }
        }
    }
};
AJS.gadgets.templater.Custom = function (options) {
    var templater = AJS.gadgets.templater.Base();
    templater.setTemplate(options.template);
    if (options.descriptor) {
        templater.setDescriptor(options.descriptor)
    }
    if (options.callback) {
        templater.addCallback(options.callback)
    }
    if (options.cache === false) {
        templater.disableCache()
    }
    AJS.$.extend(templater, {
        getTarget: function () {
            return options.target
        }
    });
    if (options.args) {
        AJS.$(options.args).each(function () {
            if (this.ajaxOptions) {
                templater.setRemoteDescriptorArg(this.key, this.ajaxOptions)
            } else {
                templater.setDescriptorArg(this)
            }
        })
    }
    return templater
};
AJS.gadgets.templater.Form = function (options) {
    return AJS.gadgets.templater.Custom(AJS.$.extend({
        template: AJS.gadgets.templater.Form.template,
        baseUrl: AJS.gadget.getBaseUrl(),
        callback: function (response, data) {
            if (options.target) {
                options.target.html(response);
                if (options.submit) {
                    AJS.$("form", options.target).submit(options.submit)
                }
                if (options.cancel) {
                    AJS.$("input.cancel", options.target).click(options.cancel)
                }
                AJS.$(data.fields).each(function () {
                    if (this.type === "callbackBuilder") {
                        var targetDiv = AJS.$("div#" + this.id);
                        this.callback(targetDiv)
                    }
                })
            } else {
                return response
            }
        }
    }, options))
};
AJS.gadgets.templater.Table = function (options) {
    var table, sortCol, sortOrd = [],
        sort = function (data, column, order) {
            data.cols[column].theme = order;
            if (!data.cols[column].sorted) {
                data.data.sort(function (item, compareItem) {
                    var dataItem = item[column].value,
                        dataItemCompare = compareItem[column].value;
                    if (!isNaN(parseFloat(dataItem)) && !isNaN(parseFloat(dataItemCompare))) {
                        dataItem = parseFloat(dataItem);
                        dataItemCompare = parseFloat(dataItemCompare)
                    }
                    if (dataItem > dataItemCompare) {
                        return 1
                    } else {
                        if (dataItem < dataItemCompare) {
                            return -1
                        } else {
                            return 0
                        }
                    }
                })
            }
            if (order === "desc") {
                data.data.reverse()
            }
            return data
        },
        templater = AJS.gadgets.templater.Custom(AJS.$.extend({
            template: AJS.gadgets.templater.Table.template,
            baseUrl: AJS.gadget.getBaseUrl(),
            cache: false
        }, options));
    if (options.sortable) {
        templater.addCallback = function (addCallback) {
            return function (callback) {
                addCallback(function (wrappedCallback) {
                    return function (newTable) {
                        AJS.$("th", newTable).click(function () {
                            sortCol = AJS.$.inArray(this, AJS.$("th", newTable));
                            if (sortOrd[sortCol]) {
                                sortOrd[sortCol].reverse()
                            }
                            templater.build()
                        });
                        if (table) {
                            table.replaceWith(newTable)
                        }
                        table = newTable;
                        wrappedCallback.call(templater, table)
                    }
                }(callback))
            }
        }(templater.addCallback);
        templater.build = function (build) {
            return function (data) {
                if (data) {
                    if (sortCol === undefined) {
                        AJS.$(data.cols).each(function (i) {
                            if (this.sort) {
                                sortCol = i;
                                if (!sortOrd[sortCol]) {
                                    sortOrd[sortCol] = [this.sort, this.sort == "asc" ? "desc" : "asc"]
                                }
                            }
                        })
                    }
                    if (sortCol !== undefined) {
                        if (!sortOrd[sortCol]) {
                            sortOrd[sortCol] = ["desc", "asc"]
                        }
                        data = sort(data, sortCol, sortOrd[sortCol][0])
                    }
                }
                build.call(templater, data)
            }
        }(templater.build)
    }
    return templater
};
AJS.gadgets.templater.Form.template = "<% var i18nHelper = new gadgets.Prefs(); %><% function createCheckboxGroup (field) { %><fieldset class=\"group<% if (field.styleClass) { %><%= gadgets.util.escape(field.styleClass) %><% } %>\"        <% if (field.id) { %>id=\"<%= gadgets.util.escape(field.id) %>\"<% } %>    ><% if ( field.label ) { %><legend><span><%= gadgets.util.escape(field.label) %></span></legend><% } %>        <% for (var i=0; i < field.options.length; i++) { %>            <div class=\"checkbox\">                <input class=\"checkbox\" type=\"checkbox\"                    <% if (field.options[i].id) { %>                        id=\"<%= gadgets.util.escape(field.options[i].id) %>\"                    <% } else { %>                        id=\"<%= gadgets.util.escape(field.userpref + \"-\" + i) %>\"                    <% } %>                    <%                    var selected = field.options[i].selected === true || field.value === \"true\";                    if(!selected && field.selected !== undefined && field.selected.length > 0) {                        for(var j = 0; j < field.selected.length; j++) {                            if(field.selected[j] === field.options[i].value) {                                selected = true;                                break;                            }                        }                    }                    if (selected) { %>                        checked = \"checked\"                    <% } %>                    <% if (field.value === \"false\") { field.value = \"true\"; } %>                    value=\"<%= field.options[i].value || field.value %>\"                    name=\"<%= gadgets.util.escape(field.userpref) %>\"                />                <% if (field.options[i].label) { %>                    <label                        <% if (field.options[i].id) { %>                            for=\"<%= gadgets.util.escape(field.options[i].id) %>\"                        <% } else { %>                            for=\"<%= gadgets.util.escape(field.userpref + \"-\" + i) %>\"                        <% } %>                    ><%= gadgets.util.escape(field.options[i].label) %></label>                <% } %>                <div class=\"error\"></div>            </div>        <% } %>        <% if (field.description) { %>    <div class=\"description\"><%= field.description %></div>        <% } %></fieldset><% } %><% function createRadioGroup (field) { %><fieldset class=\"group<% if (field.styleClass) { %><%= gadgets.util.escape(field.styleClass) %><% } %>\"        <% if (field.id) { %>id=\"<%= gadgets.util.escape(field.id) %>\"<% } %>    ><% if ( field.label ) { %><legend><span><%= gadgets.util.escape(field.label) %></span></legend><% } %><% for (var i=0; i < field.options.length; i++) { %><div class=\"radio\"><input type=\"radio\" class=\"radio\"<% if (field.options[i].id) { %>id=\"<%= gadgets.util.escape(field.options[i].id) %>\"<% } else { %>id=\"<%= gadgets.util.escape(field.userpref + \"-\" + i) %>\"<% } %><% if (field.selected === field.options[i].value || field.options[i].selected) { %>checked = \"checked\"<% } %>                        <% if ( field.options[i].value ) { %>                            value=\"<%= gadgets.util.escape(field.options[i].value) %>\"                        <% } %>name=\"<%= gadgets.util.escape(field.userpref) %>\"/><label<% if (field.options[i].id) { %>for=\"<%= gadgets.util.escape(field.options[i].id) %>\"<% } else { %>for=\"<%= gadgets.util.escape(field.userpref + \"-\" + i) %>\"<% } %>><%= gadgets.util.escape(field.options[i].label) %></label><div class=\"error\"></div></div><% } %>        <% if (field.description) { %>    <div class=\"description\"><%= field.description %></div>        <% } %></fieldset><% } %><% function createHiddenInput (field) { %><input type=\"hidden\" name=\"<%= gadgets.util.escape(field.userpref) %>\" value=\"<%= gadgets.util.escape(field.value) %>\" /><% } %><% function createTextInput (field) { %><input type=\"<%= gadgets.util.escape(field.type) %>\"<% if (field.styleClass) { %>class=\"<%= gadgets.util.escape(styleClass) %>\"<% } else { %>class=\"<%= gadgets.util.escape(field.type) %>\"<% } %>        <% if (field.value) { %>            value=\"<%= gadgets.util.escape(field.value) %>\"        <% } %>        <% if (!field.id) { %>id=\"<%= gadgets.util.escape(field.userpref) %>\"<% } else { %>id=\"<%= gadgets.util.escape(field.id) %>\"<% } %>name=\"<%= gadgets.util.escape(field.userpref) %>\"/>    <% if (field.auiIcon) { %>        <span class=\"aui-icon <%= field.auiIcon %>\"/>    <% } %>    <div class=\"error\"></div>    <% if (field.description) { %>        <div class=\"description\"><%= field.description %></div><% } %><% } %><% function createLabel (field) { %><label for=\"<%= gadgets.util.escape(field.userpref) %>\"><%= gadgets.util.escape(field.label) %></label><% } %><% function createTextarea (field) { %><textarea <% if (field.styleClass) { %>class=\"<%= gadgets.util.escape(field.styleClass) %>\"<% } %>        <% if (!field.id) { %>id=\"<%= gadgets.util.escape(field.userpref) %>\"<% } else { %>id=\"<%= gadgets.util.escape(field.id) %>\"<% } %>name=\"<%= gadgets.util.escape(field.userpref) %>\"><% if (field.value) { %><%= gadgets.util.escape(field.value) %><% } %></textarea>    <% if (field.auiIcon) { %>        <span class=\"aui-icon <%= field.auiIcon %>\"/>    <% } %><div class=\"error\"></div><% if (field.description) { %>        <div class=\"description\"><%= field.description %></div>    <% } %><% } %><% function createSelect (field) { %><% function createOption (item) { %><option    <% if ( item.id) { %>    id = \"<%= gadgets.util.escape(item.id) %>\"<% } %>    value=\"<%= gadgets.util.escape(item.value) %>\"<% if ( field.selected === item.value || item.selected) { %>    selected = \"selected\"<% } %>><%= gadgets.util.escape(item.label) %></option><% } %><select<% if (field.styleClass) { %>class=\"<%= gadgets.util.escape(field.styleClass) %>\"<% } else { %>            class=\"select\"        <% } %><% if (!field.id) { %>id=\"<%= gadgets.util.escape(field.userpref) %>\"<% } else { %>id=\"<%= gadgets.util.escape(field.id) %>\"<% } %>name=\"<%= gadgets.util.escape(field.userpref) %>\"><% for ( var i = 0; i < field.options.length; i++ ) { %><% if ( field.options[i].group ) { %><optgroup label=\"<%= gadgets.util.escape(field.options[i].group.label) %>\">                   <% if (field.options[i].group.options) { %>                        <% for ( var x = 0; x < field.options[i].group.options.length; x++ ) { %>                            <% createOption(field.options[i].group.options[x]); %>                        <% } %>                   <% } %></optgroup><% } else { %><% createOption(field.options[i]); %><% } %><% } %></select>    <% if (field.auiIcon) { %>        <span class=\"aui-icon <%= field.auiIcon %>\"/>    <% } %><div class=\"error\"></div><% if (field.description) { %>        <div class=\"description\"><%= field.description %></div>    <% } %><% } %><% function createMultiSelect (field) { %><% function createOption (item) { %><option    <% if ( item.id) { %>    id = \"<%= gadgets.util.escape(item.id) %>\"<% } %>value=\"<%= gadgets.util.escape(item.value) %>\"<%var selected = (item.selected === true);                if (typeof field.selected === \"string\") {                    field.selected = field.selected.split(\"|\");                }                if(!selected && field.selected !== undefined && field.selected.length > 0) {    for(var i = 0; i < field.selected.length; i++) {        if(field.selected[i] === item.value) {            selected = true;            break;        }    }}if (selected) { %>    selected = \"selected\"<% } %>><%= gadgets.util.escape(item.label) %></option><% } %><select multiple=\"multiple\"<% if (field.styleClass) { %>class=\"<%= gadgets.util.escape(field.styleClass) %>\"<% } else { %>            class=\"multi-select\"        <% } %><% if (!field.id) { %>id=\"<%= gadgets.util.escape(field.userpref) %>\"<% } else { %>id=\"<%= gadgets.util.escape(field.id) %>\"<% } %>name=\"<%= gadgets.util.escape(field.userpref) %>\"><% for ( var i = 0; i < field.options.length; i++ ) { %><% if ( field.options[i].group ) { %><optgroup label=\"<%= gadgets.util.escape(field.options[i].group.label) %>\"><% for ( var x = 0; x < field.options[i].group.options.length; x++ ) { %><% createOption(field.options[i].group.options[x]); %><% } %></optgroup><% } else { %><% createOption(field.options[i]); %><% } %><% } %></select>    <% if (field.auiIcon) { %>        <span class=\"aui-icon <%= field.auiIcon %>\"/>    <% } %><div class=\"error\"></div><% if (field.description) { %>        <div class=\"description\"><%= field.description %></div>    <% } %><% } %><% function createField(field, type) { %><% if (type !== \"inline\" && field.type !== \"radio\" && field.type !== \"checkbox\" && field.type !== \"hidden\") { %>        <div class=\"field-group\"><% } %><% if (field.type !== \"radio\" && field.type !== \"checkbox\"&& field.type !== \"hidden\") { %><% createLabel(field); %><% } %><% if (field.type == \"select\") { %><% createSelect(field); %>    <% } else if (field.type == \"multiselect\") { %><% createMultiSelect(field); %><% } else if (field.type == \"textarea\") { %><% createTextarea(field); %><% } else if (field.type == \"radio\") { %><% createRadioGroup(field); %><% } else if (field.type == \"checkbox\") { %><% createCheckboxGroup(field); %><% } else if (field.type == \"custom\" && field.template) { %><%= field.template() %>        <div id=\"<%= field.userpref %>-error\" class=\"error\"></div><% } else if (field.type == \"callbackBuilder\") { %>        <% if (field.id){%>            <div id=\"<%=field.id%>\" class=\"builder-container\"></div>        <% } else { %>            <div class=\"builder-container\"></div>        <% } %>        <div id=\"<%= field.userpref %>-error\" class=\"error\"></div><% } else if (field.type == \"hidden\") { %><% createHiddenInput(field); %><% } else { %><% createTextInput(field); %><% } %><% if (type !== \"inline\" && field.type !== \"radio\" && field.type !== \"checkbox\" && field.type !== \"hidden\") { %></div><% } %><% } %><% function createFieldset (fieldset, type) { %><fieldset><% if (fieldset.title) { %><legend><span><%= gadgets.util.escape(fieldset.title) %></span></legend><% } %><% if (fieldset.description) { %><p><%= gadgets.util.escape(fieldset.description) %></p><% } %><% for ( var i = 0; i < fieldset.fields.length; i++ ) { %><% createField(fieldset.fields[i], type); %><% } %></fieldset><% } %><form action=\"<%= gadgets.util.escape(obj.action || \'\') %>\" method=\"post\" class=\"aui <%= gadgets.util.escape(obj.theme || \'\') %>\">    <% if (obj.title) { %>        <h2><%= gadgets.util.escape(obj.title) %></h2><% } %><% if (obj.description ) { %><p><%= gadgets.util.escape(obj.description) %></p><% } %><% if (obj.fieldsets) { %><% for ( var i = 0; i < obj.fieldsets.length; i++ ) { %><% createFieldset(obj.fieldsets[i], obj.type); %><% } %><% } else if (obj.fields && obj.fields.length > 0) { %><% for ( var i = 0; i < obj.fields.length; i++ ) { %><% createField(obj.fields[i], obj.theme); %><% } %><% } %>    <div class=\"buttons-container\">        <div class=\"buttons\">            <input class=\"button save\" type=\"submit\" value=\"<%= i18nHelper.getMsg(\'gadget.common.save\') %>\">            <input class=\"button cancel\" type=\"button\" value=\"<%= i18nHelper.getMsg(\'gadget.common.cancel\') %>\">        </div>    </div></form>";
AJS.gadgets.templater.Table.template = "<table class=\"aui\" cellspacing=\"0\" border=\"0\">     <% if (obj.cols) { %>     <thead>         <tr>             <% AJS.$(obj.cols).each(function () { %>                 <th                 <% if (this.theme) { %>                      class=\"<%= this.theme %>\"                 <% } %>                 ><div><%= gadgets.util.escape(this.header) %></div></th>            <% }); %>         </tr>     </thead>     <% } %>     <% if (obj.data) { %>     <tbody>         <% AJS.$(obj.data).each(function (i) { %>             <tr             <% if (i%2) { %>                  class=\"even\"             <% } %>             >                 <% AJS.$(this).each(function () { %>                     <td><%= this.label %></td>                <% }); %>             </tr>         <% }); %>     </tbody>     <% } %> </table>";
AJS.debug = false;
AJS.$.namespace("AJS.gadget");
if (!console.warn) {
    console.warn = function () {}
}
Raphael = {
    shadow: function () {
        return AJS.$("<div />")
    }
};
(function () {
    function getMessage(clss, body) {
        return '<div class="aui-message ' + clss + '">\n' + '    <p><span class="aui-icon icon-' + clss + '"></span>' + body + "</p>\n" + "</div>"
    }
    AJS.messages = {
        error: function (container, options) {
            return container.html(getMessage("error", options.body))
        },
        warning: function (container, options) {
            return container.html(getMessage("warning", options.body))
        },
        info: function (container, options) {
            return container.html(getMessage("info", options.body))
        },
        setup: function () {}
    }
})();
var Gadget = function (options) {
        if (AJS.debug) {
            AJS.$.aop.around({
                target: gadgets.io,
                method: "makeRequest"
            }, function (invocation) {
                var url = invocation.arguments[0];
                if (!/\?/.test(url)) {
                    url += "?"
                } else {
                    if (!/&$/.test(url)) {
                        url += "&"
                    }
                }
                invocation.arguments[0] = url + "cacheBuster=" + new Date().getTime();
                return invocation.proceed()
            })
        }
        var prefs = new gadgets.Prefs(),
            viewMode, isAtlassianContainer = function () {
                return window._args && _args().container === "atlassian" && window.top.AG && window.top.AG.DashboardManager
            },
            getMenu = function () {
                var res = {};

                function getFooterMenu() {
                    if (!getMenu.dropdown) {
                        res.$("<div class='aui-dd-parent'><a href='#' class='aui-dd-link'><span></span></a><ul class='hidden aui-dropdown'></ul></div>").appendTo(gadget.getFooter());
                        getMenu.elem = res.$(".aui-dropdown", gadget.getFooter());
                        getMenu.dropdown = res.$(".footer .aui-dd-parent").dropDown("Standard", {
                            trigger: ".aui-dd-link",
                            selectionHandler: function (e) {
                                e.preventDefault()
                            }
                        })[0];
                        AJS.$(".gadget").addClass("needs-min");
                        gadget.resize()
                    }
                    return getMenu.elem
                }
                if (isAtlassianContainer()) {
                    res.$ = window.top.AJS.$;
                    getMenu.dropdown = res.$("#" + window.name + "-renderbox").get(0).getGadgetInstance().getElement().dropdown;
                    res.elem = getMenu.dropdown.$
                } else {
                    res.$ = AJS.$;
                    res.elem = getFooterMenu()
                }
                return res
            },
            message = function () {
                var msgContainer;

                function showPopup(msg, classNm, dismissible) {
                    var messageEl, buttons, cancelButton, buttonPanel;
                    if (classNm == "error" || classNm == "info") {
                        classNm += "-inner"
                    }
                    messageEl = AJS.$("<div />").addClass(classNm).css({
                        width: 260,
                        visiblity: "hidden"
                    }).html(msg).appendTo("body");
                    buttons = AJS.$("button", messageEl);
                    if (dismissible !== false) {
                        cancelButton = AJS.$("<button class='cancel'>").text(prefs.getMsg("gadget.common.cancel")).click(message.hide)
                    }
                    if (buttons.length > 0 || cancelButton) {
                        buttonPanel = AJS.$("<div class='buttons'>").append(buttons).append(cancelButton);
                        messageEl.append(buttonPanel)
                    }
                    message.hide();
                    msgContainer = new AJS.popup(messageEl.outerWidth(), messageEl.outerHeight(), "message");
                    msgContainer.element.html(messageEl);
                    msgContainer.show();
                    AJS.$(".blanket").show()
                }
                function showInline(msg, classNm, dismissible) {
                    if (!AJS.messages[classNm]) {
                        console.warn("Invalid class name '" + classNm + "' specified for styling AUI Message. Defaulting to error.");
                        classNm = "error"
                    }
                    message.hide();
                    msgContainer = AJS.$('<div id="gadgetMessage" />').prependTo("body .gadget .view");
                    AJS.messages[classNm](msgContainer, {
                        body: msg,
                        closeable: dismissible
                    })
                }
                return {
                    show: function (msg, classNm, dismissible, usePopup) {
                        if (usePopup) {
                            showPopup(msg, classNm, dismissible)
                        } else {
                            showInline(msg, classNm, dismissible)
                        }
                    },
                    hide: function () {
                        if (msgContainer) {
                            msgContainer.remove();
                            AJS.$(".aui-blanket").remove();
                            AJS.dim.dim = undefined
                        }
                    }
                }
            }(),
            gadget = {
                isAtlassianContainer: function () {
                    return isAtlassianContainer()
                },
                addMenuItem: function (clss, title, handler) {
                    var menu = getMenu(true);
                    if (menu.$("." + clss, menu.elem).length === 0) {
                        menu.$("<li class='dropdown-item " + clss + "'><a class='item-link no_target' href='#'>" + title + "</a></li>").click(handler).appendTo(menu.elem);
                        if (!menu.elem.is(":visible")) {
                            menu.elem.parent().show()
                        }
                    } else {
                        menu.$("." + clss, menu.elem).unbind("click").bind("click", handler)
                    }
                    getMenu.dropdown.reset()
                },
                removeMenuItem: function (clss) {
                    var menu = getMenu();
                    if (menu) {
                        window.setTimeout(function () {
                            menu.$("." + clss, menu.elem).remove();
                            if (menu.$("li", menu.elem).length === 0) {
                                menu.elem.parent().hide()
                            }
                        }, 10)
                    }
                    getMenu.dropdown.reset()
                },
                createCookie: function (name, value, days) {
                    if (days) {
                        var date = new Date();
                        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
                        var expires = "; expires=" + date.toGMTString()
                    } else {
                        var expires = ""
                    }
                    document.cookie = window.name + name + "=" + value + expires + "; path=/"
                },
                readCookie: function (name) {
                    var nameEQ = window.name + name + "=";
                    var ca = document.cookie.split(";");
                    for (var i = 0; i < ca.length; i++) {
                        var c = ca[i];
                        while (c.charAt(0) == " ") {
                            c = c.substring(1, c.length)
                        }
                        if (c.indexOf(nameEQ) == 0) {
                            return c.substring(nameEQ.length, c.length)
                        }
                    }
                    return null
                },
                eraseCookie: function (name) {
                    gadget.createCookie(window.name + name, "", -1)
                },
                showMessage: function (type, msg, dismissible, usePopup) {
                    message.show(msg, type, dismissible, usePopup)
                },
                savePref: function (name, value) {
                    if (!AJS.$.isArray(value)) {
                        prefs.set(name, value)
                    } else {
                        prefs.setArray(name, value)
                    }
                },
                setViewMode: function (mode) {
                    if (viewMode) {
                        gadget.getGadget().removeClass(viewMode)
                    }
                    gadget.getGadget().addClass(mode);
                    viewMode = mode
                },
                getViewMode: function () {
                    return viewMode
                },
                getBaseUrl: function () {
                    return options.baseUrl
                },
                getPrefs: function () {
                    return prefs
                },
                getPref: function (name) {
                    return prefs.getString(name)
                },
                getPrefArray: function (name) {
                    return prefs.getArray(name)
                },
                getMsg: function (key, params) {
                    var msg = prefs.getMsg(key);
                    if (params instanceof Array) {
                        params.splice(0, 0, msg);
                        msg = AJS.format.apply(window, params)
                    } else {
                        if (typeof params === "string") {
                            msg = AJS.format.apply(window, [msg, params])
                        }
                    }
                    return msg !== "" ? msg : key
                },
                getGadget: function () {
                    var gadget = AJS.$("<div />").addClass("gadget").appendTo("body");
                    return function () {
                        return gadget
                    }
                }(),
                resize: function (size) {
                    if (gadgets.window.adjustHeight) {
                        gadget.resize.pending = false;
                        window.setTimeout(function () {
                            gadgets.window.adjustHeight(size)
                        }, 0)
                    }
                },
                isLocal: function () {
                    if (typeof atlassian !== "undefined" && atlassian.util) {
                        return atlassian.util.getRendererBaseUrl() === options.baseUrl
                    }
                },
                showLoading: function () {
                    if (gadgets.window.getViewportDimensions && gadgets.window.getViewportDimensions().width < 250) {
                        AJS.$("body").addClass("loading-small")
                    } else {
                        AJS.$("body").addClass("loading")
                    }
                },
                hideLoading: function () {
                    AJS.$("body").removeClass("loading").removeClass("loading-small");
                    if (!AJS.$("body").hasClass("loading") && gadget.hideLoading.callbacks) {
                        AJS.$.unique(gadget.hideLoading.callbacks);
                        AJS.$.each(gadget.hideLoading.callbacks, function () {
                            this()
                        });
                        delete gadget.hideLoading.callbacks
                    }
                },
                ajaxErrorHandler: {
                    handle500: function (evt, response, settings) {
                        gadget.showMessage("error", AJS.format(gadget.getMsg("gadget.common.error.500"), settings.url, settings.url), false)
                    },
                    handle503: function (evt, response, settings) {
                        gadget.showMessage("error", response.data.errorMessages, false)
                    },
                    handle404: function (evt, response, settings) {
                        gadget.showMessage("error", AJS.format(gadget.getMsg("gadget.common.error.404"), settings.url, settings.url), false)
                    },
                    execute: function (evt, response, settings) {
                        if (response && gadget.ajaxErrorHandler["handle" + response.rc]) {
                            gadget.ajaxErrorHandler["handle" + response.rc].apply(gadget, arguments)
                        }
                    }
                }
            };
        if (AJS.debug) {
            AJS.$(["error.500", "error.404", "oauth.approve.button", "oauth.approve.message", "container.login"]).each(function () {
                if (prefs.getMsg("gadget.common." + this) === "") {
                    console.warn('il8n key missing:"' + "gadget.common." + this + '"')
                }
            });
            if (!options.baseUrl) {
                throw "@constructor Gadget: \n baseUrl is required but has not been set"
            }
            if (!(gadgets && gadgets.oauth && gadgets.oauth.Popup)) {
                throw "@constructor Gadget: \n This framework requires support for oauth. Please add the following lines to" + "<ModulePrefs> in your gadget XML:\n" + '<Require feature="oauthpopup" />\n' + "#oauth"
            }
        }
        function setTarget() {
            if (!AJS.$(this).attr("target")) {
                AJS.$(this).attr({
                    target: "_parent"
                })
            }
        }
        AJS.$("a:not(.no_target), area").live("click", setTarget).live("mouseover", setTarget);
        AJS.gadget.getBaseUrl = function () {
            return options.baseUrl
        };
        if (options.useOauth && !gadget.isLocal()) {
            AJS.$.ajax = function (ajax) {
                var queue = [],
                    trustedAppsDenied = function () {
                        if (AJS.debug) {
                            console.log("@method trustedAppsDenied:\nNot using trusted apps");
                            console.log("@method trustedAppsDenied:\nChecking for oauth token")
                        }
                        ajax({
                            authorization: "oauth",
                            url: options.useOauth,
                            data: {
                                cacheBuster: new Date().getTime()
                            },
                            useToken: "always",
                            complete: function (response) {
                                if (response.oauthApprovalUrl || response.rc === 403) {
                                    if (AJS.debug) {
                                        console.log("@method trustedAppsDenied:\noauth token not found");
                                        console.log("@method trustedAppsDenied:\nstoring approval url\n" + response.oauthApprovalUrl)
                                    }
                                    gadget.approvalUrl = response.oauthApprovalUrl;
                                    if (response.oauthApprovalUrl) {
                                        gadget.approvalRequest = queue[0]
                                    }
                                    handleOauthApproval()
                                } else {
                                    if (response.data) {
                                        if (AJS.debug) {
                                            console.log("@method trustedAppsDenied:\noauth token found");
                                            console.log("@method trustedAppsDenied:\nrequesting resource using oauth")
                                        }
                                        gadget.appendApprovedButton();
                                        makeOAuthRequests()
                                    }
                                }
                            }
                        })
                    },
                    trustedAppsAccepted = function () {
                        if (AJS.debug) {
                            console.log("@method trustedAppsAccepted: \nDetected trusted apps. Using gadgets.io.makeRequest.")
                        }
                        AJS.$.ajax = ajax;
                        AJS.$(queue).each(function () {
                            AJS.$.ajax(this)
                        })
                    },
                    makeOAuthRequests = function () {
                        AJS.$.ajax = ajax;
                        AJS.$.ajaxSetup({
                            authorization: "oauth",
                            useToken: "always"
                        });
                        AJS.$(queue).each(function () {
                            AJS.$.ajax(this)
                        })
                    },
                    handleOauthApproval = function () {
                        if (AJS.debug) {
                            console.log("@method handleOauthApproval: \noauth available")
                        }
                        if (AJS.debug) {
                            console.log("@method handleOauthApproval: \nDetecting if @anonymous access is available")
                        }
                        AJS.$.ajaxSetup({
                            authorization: "oauth",
                            useToken: "if_available"
                        });
                        var attachApprovalAdvice = function (request, idx) {
                                var cacheBuster = new Date().getTime();
                                request.complete = function (complete) {
                                    return function (response) {
                                        if (idx === queue.length - 1 && gadget.approvalRequest) {
                                            var failure200 = !! (response.rc === 200 && response.data && response.data.errorMessage);
                                            if (response.rc === 200 && !failure200 || response.rc === 400 && response.data) {
                                                if (AJS.debug) {
                                                    console.log("@method handleOauthApproval: \n@anonymous access available. " + "Proceeding with anonymous data.");
                                                    console.log("@method handleOauthApproval: \nAppending approve button to footer")
                                                }
                                                if (gadget.appendFooterApproval) {
                                                    gadget.appendFooterApproval(request)
                                                }
                                            } else {
                                                if (gadget.appendViewApproval && gadget.approvalRequest) {
                                                    if (AJS.debug) {
                                                        console.log("@method handleOauthApproval: \n@anonymous access NOT available. ");
                                                        console.log("@method handleOauthApproval: \nClearing view and displaying approve " + "button in center of gadget")
                                                    }
                                                    gadget.appendViewApproval(request)
                                                }
                                            }
                                        }
                                        if (complete) {
                                            complete.apply(AJS.$.ajax, arguments)
                                        }
                                    }
                                }(request.complete);
                                if (typeof request.data === "object") {
                                    request.data.cacheBuster = cacheBuster
                                } else {
                                    if (typeof request.data === "string") {
                                        request.data += "&cacheBuster=" + cacheBuster
                                    } else {
                                        request.data = "cacheBuster=" + cacheBuster
                                    }
                                }
                                if (!gadget.approvalRequest) {
                                    request.global = false;
                                    var normalSuccess = request.success;
                                    request.success = function (response) {
                                        if (response.errorMessage) {
                                            handleAuthFailure()
                                        } else {
                                            normalSuccess(response)
                                        }
                                    };
                                    request.error = function (response) {
                                        if (response.rc === 400 || response.rc === 401) {
                                            handleAuthFailure()
                                        }
                                    };
                                    var handleAuthFailure = function () {
                                            AJS.$("body").addClass("requires-oauth").append(gadget.getMsg("gadget.common.container.oauth.required"));
                                            if (window.top.document) {
                                                AJS.$("#" + window.name + "-chrome", window.top.document).css("opacity", 0.7)
                                            }
                                            gadget.resize()
                                        }
                                }
                                return request
                            };
                        AJS.$.ajax = ajax;
                        AJS.$(queue).each(function (i) {
                            AJS.$.ajax(attachApprovalAdvice(this, i))
                        })
                    };
                return function (settings) {
                    if (options.useOauth === "always") {
                        AJS.$.ajaxSetup({
                            authorization: "oauth",
                            useOauth: "always"
                        });
                        settings.success = function (success) {
                            return function (response) {
                                if (response.oauthApprovalUrl) {
                                    gadget.approvalUrl = response.oauthApprovalUrl;
                                    gadget.appendViewApproval(settings)
                                } else {
                                    if (success) {
                                        gadget.appendApprovedButton();
                                        success.apply(AJS.$.ajax, arguments)
                                    }
                                }
                            }
                        }(settings.success);
                        AJS.$.ajax = ajax;
                        settings.useToken = "always";
                        AJS.$.ajax(settings)
                    } else {
                        gadget.showLoading();
                        AJS.$.ajax = function (ajaxSettings) {
                            queue.push(ajaxSettings);
                            return arguments.callee
                        }(settings);
                        if (AJS.debug) {
                            console.log("@method AJS.$.ajax (pointcut):\nDetecting if trusted app")
                        }
                        return ajax({
                            url: options.useOauth,
                            data: {
                                cacheBuster: new Date().getTime()
                            },
                            complete: function (response, settings) {
                                if (response.rc === 401) {
                                    trustedAppsDenied(response, settings)
                                } else {
                                    if (response.rc === 403 && response.text) {
                                        var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;
                                        gadget.showMessage("error", response.text.replace(exp, "<a href='$1' target='_blank'>$1</a>"))
                                    } else {
                                        if (response.data) {
                                            trustedAppsAccepted()
                                        } else {
                                            if (response.rc === 404 && AJS.debug) {
                                                console.error("AJS.$.ajax (pointcut): " + AJS.format("@method AJS.$.ajax (pointcut):\nYou have specified '{0}' as the " + "resource to validate authentication type (if any), however it does not exist.", settings.url))
                                            }
                                        }
                                    }
                                }
                            }
                        })
                    }
                }
            }(AJS.$.ajax)
        }(function () {
            function canBeMovedToParentFrame() {
                return !AJS.$.browser.msie && !AJS.$.browser.opera && isAtlassianContainer()
            }
            function overflowsIframeHeight() {
                return parseInt(AJS.$("body").attr("scrollHeight")) > AJS.$("body").outerHeight()
            }
            function adjustDDPositioning() {
                if (AJS.dropDown.current && AJS.dropDown.current.calculateDDPosition) {
                    AJS.dropDown.current.updateDDPosition()
                }
            }
            function parentAsContainerHandler() {
                if (!this.positionMeInParent) {
                    this.$.remove().addClass("gadget-dropdown");
                    this.shadow.remove();
                    this.shadow.appendTo(window.top.document.body);
                    this.$.appendTo(window.top.document.body);
                    this.positionMeInParent = function () {
                        var dropdownOffsets;

                        function getLeftInPercent(left) {
                            return left / window.top.AJS.$("body").width() * 100 + "%"
                        }
                        function calculateOffsets() {
                            var dropdownOffset = this.trigger.offset(),
                                iframeOffset = window.top.AJS.$("#" + window.name).offset();
                            return {
                                top: dropdownOffset.top + this.trigger.outerHeight() + iframeOffset.top,
                                left: dropdownOffset.left + iframeOffset.left + this.trigger.outerWidth() - this.$.outerWidth(),
                                width: this.$.outerWidth()
                            }
                        }
                        if (!this.trigger.is(":visible")) {
                            this.hide()
                        } else {
                            dropdownOffsets = calculateOffsets.call(this);
                            this.$.css({
                                top: dropdownOffsets.top,
                                margin: 0,
                                left: getLeftInPercent(dropdownOffsets.left),
                                right: "auto"
                            });
                            this.shadow.css({
                                left: getLeftInPercent(dropdownOffsets.left - 7),
                                top: dropdownOffsets.top,
                                right: "auto"
                            })
                        }
                    }
                }
                this.positionMeInParent()
            }
            var iframeAsContainerHandler = {
                show: function () {
                    if (overflowsIframeHeight() && gadgets.window.adjustHeight) {
                        if (AJS.$("body").attr("scrollHeight") !== AJS.$("body").height()) {
                            gadgets.window.adjustHeight(AJS.$("body").attr("scrollHeight"))
                        }
                    }
                },
                hide: function () {
                    if (AJS.$(".active .aui-dropdown").length === 0) {
                        if (iframeAsContainerHandler.restoreHeight && AJS.$("body").height() !== iframeAsContainerHandler.restoreHeight) {
                            gadget.resize(iframeAsContainerHandler.restoreHeight)
                        }
                        delete iframeAsContainerHandler.restoreHeight
                    }
                }
            };
            AJS.$(window).resize(adjustDDPositioning);
            AJS.dropDown.Standard = function (dropDown) {
                return function (options) {
                    var dropdowns;
                    options.selectionHandler = options.selectionHandler ||
                    function (e, item) {
                        if (item[0].nodeName === "A") {
                            window.top.location.href = item.attr("href")
                        } else {
                            window.top.location.href = AJS.$("a", item).attr("href")
                        }
                    };
                    dropdowns = dropDown.call(this, options);
                    AJS.$.each(dropdowns, function () {
                        if (canBeMovedToParentFrame()) {
                            if (options.positionOnShow !== false) {
                                this.addCallback("show", function () {
                                    parentAsContainerHandler.call(this)
                                })
                            }
                        } else {
                            this.trigger.focus(function () {
                                if (!iframeAsContainerHandler.restoreHeight) {
                                    iframeAsContainerHandler.restoreHeight = AJS.$("body").outerHeight()
                                }
                            });
                            this.addCallback("show", iframeAsContainerHandler.show);
                            this.addCallback("hide", iframeAsContainerHandler.hide)
                        }
                        this.trigger.mousedown(function () {
                            AJS.$.ajaxSetup({
                                globalThrobber: false
                            })
                        })
                    });
                    return dropdowns
                }
            }(AJS.dropDown.Standard);
            AJS.dropDown.Ajax = function (dropDown) {
                return function (options) {
                    options.positionOnShow = false;
                    var dropdowns = dropDown.call(this, options);
                    AJS.$.each(dropdowns, function () {
                        this.$.addClass("loading");
                        this.addCallback("reset", function () {
                            this.$.removeClass("loading")
                        });
                        if (canBeMovedToParentFrame()) {
                            this.addCallback("reset", function () {
                                var that = this;
                                parentAsContainerHandler.call(that)
                            })
                        } else {
                            this.addCallback("reset", iframeAsContainerHandler.show)
                        }
                    });
                    return dropdowns
                }
            }(AJS.dropDown.Ajax)
        })();
        AJS.$.ajaxSetup({
            dataType: "json",
            type: "get",
            baseUrl: options.baseUrl
        });
        AJS.$(document).ajaxError(gadget.ajaxErrorHandler.execute);
        AJS.$(document).ajaxOpen(function (evt, req, options) {
            if (options && options.globalThrobber !== false) {
                gadget.showLoading.apply(this, arguments)
            }
        });
        AJS.$(document).ajaxClosed(gadget.hideLoading);
        return gadget
    };
var Standard = function (options) {
        var gadget = Gadget(options);
        AJS.$.extend(gadget, {
            constructor: Standard,
            getView: function () {
                var view = AJS.$("<div />").addClass("view").appendTo(gadget.getGadget());
                return function () {
                    return view
                }
            }(),
            getFooter: function () {
                var footer = AJS.$("<div />").addClass("footer").appendTo(gadget.getGadget());
                AJS.$("body").addClass("has-footer-options");
                this.getFooter = function () {
                    return footer
                };
                return footer
            },
            getOauthPopup: function (request) {
                if (request !== undefined) {
                    gadget.lastRequest = request
                }
                request = gadget.lastRequest;
                return new gadgets.oauth.Popup(gadget.approvalUrl, null, function () {}, function () {
                    request.complete = function () {
                        window.location.reload()
                    };
                    request.useToken = "always";
                    AJS.$.ajax(request)
                })
            },
            getApprovalButton: function (request) {
                var popup = gadget.getOauthPopup(request);
                return AJS.$("<button class='oauth'>").html("<span>" + gadget.getMsg("gadget.common.oauth.approve.button") + "</span>").click(popup.createOpenerOnClick())
            },
            appendApprovedButton: function () {
                AJS.$("<span class='oauth-approved' />").appendTo(gadget.getFooter())
            },
            appendViewApproval: function (request) {
                var approvalButton = gadget.getApprovalButton(request).appendTo("body");
                AJS.$("body").addClass("oauth-view-approval");
                gadget.hideLoading();
                return approvalButton
            },
            appendFooterApproval: function (request) {
                var popup = gadget.getOauthPopup(request);
                return AJS.$("<button />").addClass("oauth").click(popup.createOpenerOnClick()).appendTo(gadget.getFooter())
            },
            containWidthOverflow: function () {
                var bodyWidth = AJS.$("body").outerWidth();
                gadget.getView().css("overflowX", "");
                gadget.getView().css("width", "");
                if (bodyWidth < parseInt(AJS.$(".view").attr("scrollWidth"))) {
                    gadget.getView().width(bodyWidth).css("overflowX", "scroll");
                    gadget.resize()
                } else {
                    if (gadget.getView().css("overflowX") === "scroll" && parseInt(gadget.getView().attr("scrollWidth")) === gadget.getView().width()) {
                        gadget.getView().css("overflowX", "");
                        gadget.getView().css("width", "")
                    }
                }
            },
            executeAfterLoading: function (invocation) {
                invocation.arguments[0] = function (callback) {
                    return function () {
                        if (AJS.$("body").hasClass("loading")) {
                            gadget.hideLoading.callbacks = gadget.hideLoading.callbacks || [];
                            gadget.hideLoading.callbacks.push(callback)
                        } else {
                            callback()
                        }
                    }
                }(invocation.arguments[0]);
                return invocation.proceed()
            },
            viewTemplate: AJS.gadgets.templater.Custom({
                template: function (args) {
                    if (gadgets.views) {
                        gadget.setViewMode(gadgets.views.getCurrentView().getName())
                    }
                    options.view.template.call(gadget, args);
                    gadget.showView(false, false);
                    if (gadget.isAtlassianContainer()) {
                        window.top.AJS.$("body").trigger("gadget-rendering-finished")
                    }
                },
                cache: false,
                args: function () {
                    var args = [];
                    AJS.$(options.view.args).each(function () {
                        if (AJS.$.isFunction(this.ajaxOptions)) {
                            var that = this;
                            args.push({
                                key: this.key,
                                ajaxOptions: function (args) {
                                    return that.ajaxOptions.call(gadget, args)
                                }
                            })
                        } else {
                            args.push(this)
                        }
                    });
                    return args
                }()
            })
        });
        AJS.$.aop.around({
            target: gadget.viewTemplate,
            method: "addCallback"
        }, gadget.executeAfterLoading);
        AJS.$.aop.around({
            target: gadget,
            method: "resize"
        }, function (invocation) {
            if (!gadget.resize.pending) {
                gadget.resize.pending = true;
                gadget.executeAfterLoading.apply(this, arguments)
            }
        });
        gadget.showView = function () {
            gadget.viewTemplate.addCallback(function () {
                window.setTimeout(function () {
                    gadget.resize()
                }, 150)
            });
            if (AJS.$.browser.msie) {
                gadget.viewTemplate.addCallback(gadget.containWidthOverflow)
            }
            return function (refresh, resize) {
                if (refresh) {
                    gadget.viewTemplate.build()
                } else {
                    gadget.getView().show();
                    if (resize !== false) {
                        gadget.resize()
                    }
                }
            }
        }();
        if (AJS.$.browser.msie) {
            AJS.$(window).resize(gadget.containWidthOverflow)
        }
        if (options.view.onResizeReload) {
            AJS.$(window).resize(function () {
                var width = gadgets.window.getViewportDimensions().width;
                return function () {
                    if (gadget.getView().is(":visible")) {
                        var newWidth = gadgets.window.getViewportDimensions().width;
                        if (width > (newWidth + 50) || width < (newWidth - 50)) {
                            gadget.showView(true);
                            width = newWidth
                        }
                    }
                }
            }())
        }
        if (options.view.onResizeAdjustHeight) {
            AJS.$(window).resize(function () {
                var width = gadgets.window.getViewportDimensions().width;
                return function () {
                    var newWidth = gadgets.window.getViewportDimensions().width;
                    if (width > (newWidth + 50) || width < (newWidth - 50)) {
                        gadget.resize();
                        width = newWidth
                    }
                }
            }())
        }
        return gadget
    };
var Configured = function (options) {
        var gadget = Standard(options);
        gadget.constructor = Configured;
        if (AJS.debug) {
            if (gadget.getPref("isConfigured") === "") {
                throw "@constructor Configured: \nGadget is spec'ed as being configured or configurable. Add " + '<UserPref name="isConfigured" datatype="hidden" default_value="false" /> to <ModulePrefs> in your ' + "gadget XML."
            }
        }
        gadget.ajaxErrorHandler.handle400 = function (evt, response) {
            if (AJS.$("body").hasClass("config-unavailable")) {
                return
            }
            var errorContainer = AJS.$("<div class='message info' />").append("<p>" + gadget.getMsg("gadget.common.config.unavailable") + "</p>").appendTo(gadget.getView()),
                errorList = AJS.$("<ul />").appendTo(errorContainer);
            AJS.$("body").addClass("config-unavailable");
            AJS.$(response.data.errors).each(function () {
                AJS.$("<li />").append("<strong>" + gadget.getMsg(this.error, this.params) + "</strong>").appendTo(errorList)
            });
            gadget.resize()
        };
        if (options.view.enableReload) {
            if (AJS.debug) {
                if (gadget.getPref("refresh") === "") {
                    throw "@constructor Configured: \n You have specified 'enableReload' for view. This feature requires you to " + 'add <UserPref name="refresh" datatype="hidden" default_value="false" /> to <ModulePrefs> ' + "in your gadget XML."
                }
            }
            if (gadget.getPref("refresh") !== "" && gadget.getPref("refresh") !== "false") {
                window.setInterval(function () {
                    gadget.showView(true)
                }, 60000 * gadget.getPref("refresh"))
            }
            gadget.addReloadButton = function () {
                gadget.addMenuItem("reload", gadget.getMsg("gadget.common.reload"), function (e) {
                    gadget.showView(true);
                    e.preventDefault()
                })
            };
            gadget.viewTemplate.addCallback(gadget.addReloadButton)
        }
        return gadget
    };
var Configurable = function (options) {
        var gadget = Configured(options);
        if (AJS.debug) {
            if (options.view.enableReload) {
                AJS.$(["refresh.never", "refresh.minutes", "refresh.hour", "refresh.hours", "refresh.description", "refresh.label"]).each(function () {
                    if (gadget.getPrefs().getMsg("gadget.common." + this) === "") {
                        console.warn('il8n key missing:"' + "gadget.common." + this + '"')
                    }
                })
            }
        }
        AJS.$.extend(gadget, {
            constructor: Configurable,
            appendFooterApproval: function (superAppendFooterApproval) {
                return function (request) {
                    if (AJS.$(".info.footer-message").length < 1) {
                        AJS.$("<div id='oauth-inline-approval' />").addClass("info footer-message").html("<p>" + gadget.getMsg("gadget.common.oauth.approve.message") + "</p>").append(gadget.getApprovalButton(request)).insertBefore(AJS.$(":first", gadget.configTemplate.getTarget()));
                        gadget.resize()
                    }
                    superAppendFooterApproval.apply(gadget, arguments)
                }
            }(gadget.appendFooterApproval),
            getOauthPopup: function (request) {
                if (request !== undefined) {
                    gadget.lastRequest = request
                }
                request = gadget.lastRequest;
                return new gadgets.oauth.Popup(gadget.approvalUrl, null, function () {}, function () {
                    request.complete = function () {
                        function persistFormInHash() {
                            window.location.href += "&" + AJS.$("form", gadget.configTemplate.getTarget()).serialize() + "}"
                        }
                        if (gadget.getPrefs().getBool("isConfigured") && !/isConfigured=true/.test(window.location.href)) {
                            persistFormInHash();
                            window.top.location.reload()
                        } else {
                            persistFormInHash();
                            window.location.reload()
                        }
                    };
                    request.useToken = "always";
                    AJS.$.ajax(request)
                })
            },
            configTemplate: AJS.gadgets.templater.Form({
                target: AJS.$("<div id='config' />").appendTo(document.body),
                descriptor: function (args) {
                    var descriptor = options.config.descriptor.call(gadget, args);
                    if (options.view.enableReload) {
                        descriptor.fields.push({
                            userpref: "refresh",
                            label: gadget.getMsg("gadget.common.refresh.label"),
                            description: gadget.getMsg("gadget.common.refresh.description"),
                            selected: gadget.getPref("refresh"),
                            options: [{
                                value: "false",
                                label: gadget.getMsg("gadget.common.refresh.never")
                            }, {
                                value: "15",
                                label: AJS.format(gadget.getMsg("gadget.common.refresh.minutes"), 15)
                            }, {
                                value: "30",
                                label: AJS.format(gadget.getMsg("gadget.common.refresh.minutes"), 30)
                            }, {
                                value: "60",
                                label: AJS.format(gadget.getMsg("gadget.common.refresh.hour"), 1)
                            }, {
                                value: "120",
                                label: AJS.format(gadget.getMsg("gadget.common.refresh.hours"), 2)
                            }],
                            type: "select"
                        })
                    }
                    return descriptor
                },
                args: function () {
                    var args = [];
                    if (AJS.$.isFunction(options.config.args)) {
                        options.config.args = options.config.args()
                    }
                    AJS.$(options.config.args).each(function () {
                        var that = this;
                        if (AJS.$.isFunction(this.ajaxOptions)) {
                            args.push({
                                key: this.key,
                                ajaxOptions: function (args) {
                                    return that.ajaxOptions.call(gadget, args)
                                }
                            })
                        } else {
                            args.push(this)
                        }
                    });
                    return args
                }(),
                cancel: function (e) {
                    gadget.showView();
                    e.preventDefault()
                },
                submit: function (e) {
                    var form = AJS.$(this),
                        save = function () {
                            var fieldValues = {};
                            AJS.$(form.serializeArray()).each(function () {
                                var fieldVal = fieldValues[this.name];
                                if (!fieldVal) {
                                    fieldVal = this.value
                                } else {
                                    if (AJS.$.isArray(fieldVal)) {
                                        fieldVal.push(this.value)
                                    } else {
                                        fieldVal = [fieldVal, this.value]
                                    }
                                }
                                fieldValues[this.name] = fieldVal
                            });
                            AJS.$(":checkbox:not(:checked)", form).each(function () {
                                if (!fieldValues[this.name] || fieldValues[this.name] == "") {
                                    fieldValues[this.name] = "false"
                                }
                            });
                            for (var name in fieldValues) {
                                gadget.savePref(name, fieldValues[name])
                            }
                            gadget.showView(true)
                        };
                    if (form.attr("action") !== "") {
                        AJS.$.ajax({
                            type: "get",
                            url: form.attr("action"),
                            data: form.serialize(),
                            global: false,
                            success: function () {
                                save()
                            },
                            error: function (response, settings) {
                                gadget.ajaxErrorHandler.execute(null, response, AJS.$.extend(settings, {
                                    isConfig: true
                                }))
                            }
                        })
                    } else {
                        save()
                    }
                    e.preventDefault()
                }
            }),
            getConfig: function () {
                return gadget.configTemplate.getTarget()
            }
        });
        gadget.showConfig = function () {
            var restoreValuesFromHash = function () {
                    var options, fields;
                    if (/#/.test(window.location.href) && !/#rpctoken=[0-9]+$/.test(window.location.href)) {
                        fields = window.location.href.replace(/.*?#/, "").split("&");
                        AJS.$.each(fields, function () {
                            var name = this.split("=")[0],
                                val = decodeURIComponent(this.split("=")[1]).replace(/\+/, " "),
                                field = AJS.$(":input[name=" + name + "]");
                            if (field.length > 0) {
                                if (field.is("select")) {
                                    options = val.split(",");
                                    AJS.$.each(options, function () {
                                        AJS.$("option[value=" + this + "]", field).attr("selected", "selected")
                                    })
                                } else {
                                    if (field.is(":radio,:checkbox")) {
                                        field.attr("checked", "checked")
                                    } else {
                                        field.val(val)
                                    }
                                }
                            }
                        });
                        window.location.href = window.location.href.replace(/(#rpctoken=[0-9]+).*/, "$1")
                    }
                };
            gadget.configTemplate.addCallback(function () {
                AJS.$("body").addClass("config-active");
                gadget.configTemplate.getTarget().show();
                restoreValuesFromHash();
                if (gadget.approvalRequest) {
                    gadget.appendFooterApproval(gadget.approvalRequest)
                }
                AJS.$("button", ".footer").hide();
                gadget.resize();
                if (AJS.$.browser.msie) {
                    AJS.$("body").addClass("ie-reflow")
                }
                if (gadget.isAtlassianContainer()) {
                    window.top.AJS.$("body").trigger("gadget-rendering-finished")
                }
            });
            return function () {
                gadget.configTemplate.build()
            }
        }();
        gadget.showView = function (refresh, resize) {
            if (refresh) {
                gadget.viewTemplate.build()
            } else {
                AJS.$("body").removeClass("config-active");
                gadget.configTemplate.getTarget().hide();
                if (resize !== false) {
                    gadget.resize()
                }
                AJS.$("button", ".footer").show()
            }
            gadget.addMenuItem("configure", gadget.getMsg("gadget.common.configure"), function (e) {
                gadget.showConfig();
                e.preventDefault()
            });
            if (gadget.addReloadButton) {
                gadget.addReloadButton()
            }
        };
        gadget.ajaxErrorHandler.handle400 = function (superHandle400) {
            var validationErrors, showFormErrors = function () {
                    AJS.$(".error", gadget.configTemplate.getTarget()).hide();
                    AJS.$(validationErrors).each(function () {
                        var msg = gadget.getMsg(this.error, this.params);
                        AJS.$(":input[name='" + this.field + "']").parent().find(".error").text(msg).show();
                        AJS.$("#" + this.field + "-error").text(msg).show()
                    });
                    gadget.resize();
                    validationErrors = null
                };
            gadget.configTemplate.addCallback(function () {
                if (!gadget.getPrefs().getBool("isConfigured") || validationErrors) {
                    AJS.$("input.cancel", gadget.configTemplate.getTarget()).hide()
                }
                if (validationErrors) {
                    showFormErrors()
                }
                gadget.removeMenuItem("configure");
                gadget.removeMenuItem("reload")
            });
            return function (evt, response, settings) {
                validationErrors = response.data.errors;
                if (!settings.isConfig) {
                    superHandle400.apply(gadget, arguments)
                } else {
                    showFormErrors()
                }
            }
        }(gadget.ajaxErrorHandler.handle400);
        return gadget
    };
AJS.Gadget = function (options) {
    var gadget, pubInterface, isWriteable = function () {
            if (gadgets.views) {
                return gadgets.views.getParams().writable === undefined || gadgets.views.getParams().writable === "true"
            } else {
                if (AJS.debug) {
                    throw "@method isWriteable: \nExpected Object 'gadgets.views', however it was undefined. To get this object " + "you need to include to <Require feature='views' /> to <ModulePrefs> in your gadget XML"
                }
            }
        },
        getStandardInterface = function () {
            return {
                showMessage: gadget.showMessage,
                savePref: gadget.savePref,
                setViewMode: gadget.setViewMode,
                getViewMode: gadget.getViewMode,
                getBaseUrl: gadget.getBaseUrl,
                getPrefs: gadget.getPrefs,
                getPref: gadget.getPref,
                getPrefArray: gadget.getPrefArray,
                getMsg: gadget.getMsg,
                getGadget: gadget.getGadget,
                resize: gadget.resize,
                showLoading: gadget.showLoading,
                hideLoading: gadget.hideLoading,
                createCookie: gadget.createCookie,
                readCookie: gadget.readCookie,
                eraseCookie: gadget.eraseCookie,
                isLocal: gadget.isLocal,
                addMenuItem: gadget.addMenuItem,
                removeMenuItem: gadget.removeMenuItem
            }
        },
        getConfiguredInterface = function () {
            return AJS.$.extend(getStandardInterface(), {
                getView: gadget.getView,
                showView: gadget.showView,
                getFooter: gadget.getFooter
            })
        },
        getConfigurableInterface = function () {
            return AJS.$.extend(getConfiguredInterface(), {
                showConfig: gadget.showConfig,
                getConfig: gadget.getConfig
            })
        };
    if (options.view && !options.config) {
        gadget = Standard(options);
        pubInterface = getStandardInterface();
        gadget.showView(true)
    } else {
        if (options.view && options.config && !isWriteable()) {
            if (AJS.debug) {
                console.log("@constructor AJS.Gadget: \nConfiguration form has been excluded, user is not gadget owner and does " + "NOT have write permission")
            }
            gadget = Configured(options);
            pubInterface = getConfiguredInterface();
            if (gadget.getPrefs().getBool("isConfigured")) {
                gadget.showView(true)
            }
        } else {
            if (options.view && options.config && isWriteable()) {
                gadget = Configurable(options);
                pubInterface = getConfigurableInterface();
                if (!gadget.getPrefs().getBool("isConfigured")) {
                    gadget.showConfig()
                } else {
                    gadget.showView(true)
                }
            }
        }
    }
    return pubInterface
};
AJS.gadget.Configurable = AJS.Gadget;
AJS.$.namespace("AJS.gadget.fields");
AJS.gadget.fields.period = function (gadget, userpref) {
    return {
        userpref: userpref,
        label: gadget.getMsg("gadget.common.period.name.label"),
        description: gadget.getMsg("gadget.common.period.name.description"),
        type: "select",
        selected: gadget.getPref(userpref),
        options: [{
            label: gadget.getMsg("gadget.common.period.hourly"),
            value: "hourly"
        }, {
            label: gadget.getMsg("gadget.common.period.daily"),
            value: "daily"
        }, {
            label: gadget.getMsg("gadget.common.period.weekly"),
            value: "weekly"
        }, {
            label: gadget.getMsg("gadget.common.period.monthly"),
            value: "monthly"
        }, {
            label: gadget.getMsg("gadget.common.period.quarterly"),
            value: "quarterly"
        }, {
            label: gadget.getMsg("gadget.common.period.yearly"),
            value: "yearly"
        }]
    }
};
AJS.gadget.fields.days = function (gadget, userpref, optMsgKeys) {
    return {
        userpref: userpref,
        label: gadget.getMsg(optMsgKeys && optMsgKeys.label ? optMsgKeys.label : "gadget.common.days.label"),
        description: gadget.getMsg(optMsgKeys && optMsgKeys.description ? optMsgKeys.description : "gadget.common.days.description"),
        type: "text",
        value: gadget.getPref(userpref)
    }
};
AJS.gadget.fields.numberToShow = function (gadget, userpref) {
    return {
        userpref: userpref,
        label: gadget.getMsg("gadget.common.num.label"),
        description: gadget.getMsg("gadget.common.num.description"),
        type: "text",
        value: gadget.getPref(userpref)
    }
};
AJS.gadget.fields.cumulative = function (gadget, userpref) {
    return {
        userpref: userpref,
        label: gadget.getMsg("gadget.common.cumulative.label"),
        description: gadget.getMsg("gadget.common.cumulative.description"),
        type: "select",
        selected: gadget.getPref(userpref),
        options: [{
            label: gadget.getMsg("gadget.common.yes"),
            value: "true"
        }, {
            label: gadget.getMsg("gadget.common.no"),
            value: "false"
        }]
    }
};
AJS.gadget.fields.nowConfigured = function () {
    return {
        userpref: "isConfigured",
        type: "hidden",
        value: "true"
    }
};
AJS.gadget.fields.applyOverLabel = function (overLabelId) {
    AJS.$("#" + overLabelId).each(function () {
        var label = AJS.$(this).removeClass("overlabel").addClass("overlabel-apply").click(function () {
            AJS.$("#" + AJS.$(this).attr("for")).focus()
        });
        var field = AJS.$("#" + label.attr("for")).focus(function () {
            label.hide()
        }).blur(function () {
            if (AJS.$(this).val() === "") {
                label.show()
            }
        });
        if (field.val() !== "") {
            label.hide()
        }
    })
};